package jp.co.systemi.asp.workflow.route;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import jp.co.systemi.asp.workflow.Main;
import jp.co.systemi.asp.workflow.data.Approver;
import jp.co.systemi.asp.workflow.data.ApproverMeta;
import jp.co.systemi.asp.workflow.data.Route;
import jp.co.systemi.asp.workflow.data.RouteMeta;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.authorization.strategies.role.Roles;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.PropertyModel;
import org.datanucleus.util.StringUtils;
import org.slim3.datastore.Datastore;

import com.google.appengine.api.datastore.Key;
@AuthorizeInstantiation(Roles.ADMIN)
public class RouteEdit extends Main {

    /**
     * ログ出力 クラス名をあわせること
     */
    private static final Logger log = Logger
            .getLogger(RouteEdit.class.getName());
    private List<Approver> approvers = new ArrayList<Approver>();
    String approvee = "";	// ルート検証用
    Key routeId = null;
    Route route = null;
    String approverRole = "";
//    @FormInput		// mainにて自動addするために、下記のフィールドの宣言はpublicで必要
    // テーブルに配置するため、FormInput不要
    public TextField<String> wi_approverRole = new TextField<String>("wi_approverRole",
            new PropertyModel<String>(this, "approverRole"));
    /**
     * コンストラクター 画面の生成、イベント処理の定義はすべて、この中で完結する
     */
    public RouteEdit(PageParameters pars) {
        routeId = Datastore.createKey(Route.class, pars.getLong("routeId"));
        init();
    }
    private void init() {
        RouteMeta rm = RouteMeta.get();
        route = Datastore.query(rm).filter(rm.id.equal(routeId)).asSingle();
//        main.add(new Label("wi_routeName", new PropertyModel<Long>(this, "routeId.id")));
        main.add(new Label("wi_routeName", new PropertyModel<String>(route, "name")));
        wi_approverRole.setOutputMarkupId(true);
        // Formを生成する
        final Form<Route> form = new MainForm<Route>(this, "wi_routeEditForm");
        ApproverMeta am = ApproverMeta.get();
        List<Approver> approversOrg = Datastore.query(am).filter(am.routeId.equal(routeId)).asList();
        for(int i = 0; i < approversOrg.size(); i++){
            Approver approver = approversOrg.get(i);
            if(approver.getSeq() == null || approver.getSeq().intValue() != i + 1){
                approver.setSeq(i + 1);
                Datastore.put(approver);
            }

            approvers.add(approver);
        }
        // 承認者リスト
        final WebMarkupContainer tblApprovers = new WebMarkupContainer(
                "wi_tblApprover");
        tblApprovers.setOutputMarkupId(true);
        form.add(tblApprovers);

        // 承認者リスト
        tblApprovers.add(new ListView<Approver>("wi_trApprover", approvers){
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<Approver> item) {
                final Approver approver = (Approver)item.getModelObject();
                item.add(new Label("wi_tdSeq", new PropertyModel<Integer>(approver, "seq")));
                item.add(new Label("wi_tdApprover", new PropertyModel<String>(approver, "role")));
                item.add(new AjaxLink<Object>("wi_tdDelete") {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        log.info("delete");
                        Datastore.delete(approver.getId());
                        approvers.remove(approver);
                        // 順番を振りなおし
                        int i = 0;
                        for (Approver r : approvers) {
                            r.setSeq(++i);
                        }
                        target.addComponent(form);
                    }

                });
            }

        });

        tblApprovers.add(new AjaxButton("wi_save") {
            private static final long serialVersionUID = -2573012794536636414L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                // すべて登録しなおし
                ApproverMeta am = ApproverMeta.get();
                List<Approver> approvers = Datastore.query(am).filter(am.routeId.equal(routeId)).asList();
                for(Approver approver : approvers){
                    Datastore.delete(approver.getId());
                }
                int i = 0;
                for(Iterator<Approver> itr = approvers.iterator(); itr.hasNext(); ){
                    Approver approver = itr.next();
                    if(!StringUtils.isEmpty(approver.getRole())){
                        approver.setSeq(i + 1);
                        Datastore.put(approver);
                        i++;
                    } else {
                        itr.remove();
                    }
                }
                // メッセージをクリア
                target.addComponent(feedback);
                // テーブル再表示
                target.addComponent(tblApprovers);
                // 入力をクリア
                approverRole = "";
                target.addComponent(wi_approverRole);
            }
        });

        AjaxButton addApprover = new AjaxButton("wi_addApprover") {
            private static final long serialVersionUID = -2573012794536636414L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                if(StringUtils.isEmpty(approverRole)){
                    error(getString("approvername.empty"));
                    target.addComponent(feedback);
                    return;
                }
                for(Approver approver : approvers){
                    if(approverRole.equals(approver.getRole())){
                        error(getString("approvername.exists"));
                        target.addComponent(feedback);
                        return;
                    }
                }
                Approver approver = new Approver();
                approver.setRouteId(routeId);
                approver.setSeq(approvers.size() + 1);
                approver.setRole(approverRole);
                approvers.add(approver);

                Datastore.put(approver);
                // メッセージをクリア
                target.addComponent(feedback);
                // テーブル再表示
                target.addComponent(tblApprovers);
                // 入力をクリア
                approverRole = "";
                target.addComponent(wi_approverRole);
            }
        };
        tblApprovers.add(addApprover);
        form.setDefaultButton(addApprover);
        tblApprovers.add(wi_approverRole);
        tblApprovers.add(new AjaxButton("wi_deleteApprover") {
            private static final long serialVersionUID = -2573012794536636414L;

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                Iterator<Approver> itr = approvers.iterator();
                ApproverMeta am = ApproverMeta.get();
                while(itr.hasNext()){
                    Approver approver = itr.next();
                    if(approver.getSelect() != null && approver.getSelect()){
                       itr.remove();
                       List<Approver> approvers = Datastore.query(am).filter(am.routeId.equal(routeId),
                               am.role.equal(approver.getRole())).asList();
                       for(Approver a : approvers){
                           Datastore.delete(a.getId());
                       }
                    }
                }
                for(int i = 0; i < approvers.size(); i++){
                    approvers.get(i).setSeq(i + 1);
                }
                target.addComponent(feedback);
                target.addComponent(tblApprovers);
            }
        });

    }

}
